#include "WorldToMasterModule.h"
#include "WorldNetClientPlugin.h"
#include "PluginModule/INetClientModule.h"

bool FragrantGrass::WorldToMasterModule::Init()
{
	m_pNetClientModule = m_pPluginManager->FindModule<INetClientModule>();
	m_pNetModule = m_pPluginManager->FindModule<INetModule>();
	m_pConfigModule = m_pPluginManager->FindModule<IConfigModule>();
	m_pLogModule = m_pPluginManager->FindModule<ILogModule>();
	m_pWorldNetServerModule = m_pPluginManager->FindModule<IWorldNetServerModule>();
	m_pSecurityModule = m_pPluginManager->FindModule<ISecurityModule>();

	return true;
}

bool FragrantGrass::WorldToMasterModule::Shut()
{
	return true;
}

bool FragrantGrass::WorldToMasterModule::AfterInit()
{
	m_pNetClientModule->AddReceiveCallBack(FG_SERVER_TYPES::FG_ST_MASTER, Protocol::EGMI_REQ_CONNECT_WORLD, this, &WorldToMasterModule::OnSelectServerProcess);
	m_pNetClientModule->AddReceiveCallBack(FG_SERVER_TYPES::FG_ST_MASTER, Protocol::EGMI_REQ_KICK_CLIENT_INWORLD, this, &WorldToMasterModule::OnKickClientProcess);
	m_pNetClientModule->AddReceiveCallBack(FG_SERVER_TYPES::FG_ST_MASTER, this, &WorldToMasterModule::InvalidMessage);
	m_pNetClientModule->AddReceiveCallBack(FG_SERVER_TYPES::FG_ST_MASTER, Protocol::EGMI_STS_NET_INFO, this, &WorldToMasterModule::OnServerInfoProcess);
	m_pNetClientModule->AddEventCallBack(FG_SERVER_TYPES::FG_ST_MASTER, this, &WorldToMasterModule::OnSocketMSEvent);
	m_pNetClientModule->ExpandBufferSize();

	const Protocol::ServerInfoReportList& serverInfoList = *(const Protocol::ServerInfoReportList*)m_pConfigModule->GetConfigDatas(IConfigModule::FileParseType::FPT_SERVER_DATA);
	int n = serverInfoList.server_list_size();
	for (int i = 0; i < n; ++i)
	{
		const Protocol::ServerInfoReport& serverInfo = serverInfoList.server_list(i);
		const int nServerType = serverInfo.server_type();
		const int nServerID = serverInfo.server_id();
		if (nServerType == FG_SERVER_TYPES::FG_ST_MASTER)
		{
			const int nPort = serverInfo.server_port();
			const int nMaxConnect = serverInfo.server_max_online();
			const int nCpus = serverInfo.server_cur_count();
			const std::string& strName = serverInfo.server_name();
			const std::string& strIP = serverInfo.server_ip();
			const int strId = serverInfo.server_id();
			
			ConnectData xServerData;
			xServerData.nGameID = nServerID;
			xServerData.eServerType = (FG_SERVER_TYPES)nServerType;
			xServerData.strIP = strIP;
			xServerData.nPort = nPort;
			xServerData.strName = lexical_cast<std::string>(strId);

			std::ostringstream strLog;
			strLog << "[WorldToMasterModule::AfterInit]:Add ConnectData: Ip = " << strIP;
			strLog << " Port = " << nPort;
			m_pLogModule->LogNormal(ILogModule::LL_DEBUG_NORMAL , NULL_OBJECT, strLog, __FUNCTION__, __LINE__);

			m_pNetClientModule->AddServer(xServerData);
		}
	}

	return true;
}


bool FragrantGrass::WorldToMasterModule::Execute()
{
	ServerReport();
	return true;
}

void FragrantGrass::WorldToMasterModule::Register(INet* pNet)
{
	const Protocol::ServerInfoReportList& serverInfoList = *(const Protocol::ServerInfoReportList*)m_pConfigModule->GetConfigDatas(IConfigModule::FileParseType::FPT_SERVER_DATA);
	int n = serverInfoList.server_list_size();
	for (int i = 0; i < n; ++i)
	{
		const Protocol::ServerInfoReport& serverInfo = serverInfoList.server_list(i);
		const int nServerType = serverInfo.server_type();
		const int nServerID = serverInfo.server_id();
		if (nServerType == FG_SERVER_TYPES::FG_ST_WORLD && m_pPluginManager->GetAppID() == nServerID)
		{
			const int nPort = serverInfo.server_port();
			const int nMaxConnect = serverInfo.server_max_online();
			const int nCpus = serverInfo.server_cur_count();
			const std::string& strName = serverInfo.server_name();
			const std::string& strIP = serverInfo.server_ip();
			const int strID = serverInfo.server_id();

			Protocol::ServerInfoReportList xMsg;
			Protocol::ServerInfoReport* pData = xMsg.add_server_list();
			*pData = serverInfo;

			FG_SHARE_PTR<ConnectData> pServerData = m_pNetClientModule->GetServerNetInfo(pNet);
			if (pServerData)
			{
				int nTargetID = pServerData->nGameID;
				m_pNetClientModule->SendToServerByPB(nTargetID, Protocol::EGameMsgID::EGMI_WTM_WORLD_REGISTERED, xMsg);

				m_pLogModule->LogNormal(ILogModule::LL_INFO_NORMAL, GUID(0, pData->server_id()), pData->server_name(), "ready to registe to master");
			}
		}
	}
}

void FragrantGrass::WorldToMasterModule::ServerReport()
{
	if (mLastReportTime + 10 > m_pPluginManager->GetNowTime())
	{
		return;
	}
	//mLastReportTime = m_pPluginManager->GetNowTime();
	//std::shared_ptr<NFIClass> xLogicClass = m_pClassModule->GetElement(NFrame::Server::ThisName());
	//if (xLogicClass)
	//{
	//	const std::vector<std::string>& strIdList = xLogicClass->GetIDList();
	//	for (int i = 0; i < strIdList.size(); ++i)
	//	{
	//		const std::string& strId = strIdList[i];

	//		const int nServerType = m_pElementModule->GetPropertyInt32(strId, NFrame::Server::Type());
	//		const int nServerID = m_pElementModule->GetPropertyInt32(strId, NFrame::Server::ServerID());
	//		if (m_pPluginManager->GetAppID() == nServerID)
	//		{
	//			const int nPort = m_pElementModule->GetPropertyInt32(strId, NFrame::Server::Port());
	//			const int nMaxConnect = m_pElementModule->GetPropertyInt32(strId, NFrame::Server::MaxOnline());
	//			const std::string& strName = m_pElementModule->GetPropertyString(strId, NFrame::Server::ID());
	//			const std::string& strIP = m_pElementModule->GetPropertyString(strId, NFrame::Server::IP());

	//			Protocol::ServerInfoReport reqMsg;

	//			reqMsg.set_server_id(nServerID);
	//			reqMsg.set_server_name(strId);
	//			reqMsg.set_server_cur_count(0);
	//			reqMsg.set_server_ip(strIP);
	//			reqMsg.set_server_port(nPort);
	//			reqMsg.set_server_max_online(nMaxConnect);
	//			reqMsg.set_server_state(Protocol::EST_NARMAL);
	//			reqMsg.set_server_type(nServerType);

	//			m_pNetClientModule->SendToAllServerByPB(FG_SERVER_TYPES::FG_ST_MASTER, Protocol::EGMI_STS_SERVER_REPORT, reqMsg);
	//		}
	//	}
	//}
}

void FragrantGrass::WorldToMasterModule::RefreshWorldInfo()
{

}

void FragrantGrass::WorldToMasterModule::OnSelectServerProcess(const SOCK nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	GUID nPlayerID;
	Protocol::ReqConnectWorld xMsg;
	if (!INetModule::recieve_protobuf_message( nMsgID, msg, nLen, xMsg, nPlayerID))
	{
		return;
	}

	FG_SHARE_PTR<ServerData> xServerData = m_pWorldNetServerModule->GetSuitProxyForEnter();
	if (xServerData)
	{
		const std::string& strSecurityKey = m_pSecurityModule->GetSecurityKey(xMsg.account());

		Protocol::AckConnectWorldResult xData;

		xData.set_world_id(xMsg.world_id());
		xData.mutable_sender()->CopyFrom(xMsg.sender());
		xData.set_login_id(xMsg.login_id());
		xData.set_account(xMsg.account());

		xData.set_world_ip(xServerData->pData->server_ip());
		xData.set_world_port(xServerData->pData->server_port());
		xData.set_world_key(strSecurityKey);

		m_pNetModule->send_protobuf_message(Protocol::EGMI_ACK_CONNECT_WORLD, xData, xServerData->nFD);

		m_pNetClientModule->SendSuitByPB(FG_SERVER_TYPES::FG_ST_MASTER, xMsg.account(), Protocol::EGMI_ACK_CONNECT_WORLD, xData);
	}

}

void FragrantGrass::WorldToMasterModule::OnKickClientProcess(const SOCK nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	GUID nPlayerID;
	Protocol::ReqKickFromWorld xMsg;
	if (!INetModule::recieve_protobuf_message( nMsgID, msg, nLen, xMsg, nPlayerID))
	{
		return;
	}

	
	//     NFDataList var;
	//     var << xMsg.world_id() << xMsg.account();
	//     m_pEventProcessModule->DoEvent(GUID(), NFED_ON_KICK_FROM_SERVER, var);
}

void FragrantGrass::WorldToMasterModule::InvalidMessage(const SOCK nSockIndex, const int nMsgID, const char * msg, const uint32_t nLen)
{
	printf("FGNet || unMsgID=%d\n", nMsgID);
}

void FragrantGrass::WorldToMasterModule::OnSocketMSEvent(const SOCK nSockIndex, const FG_NET_EVENT eEvent, INet* pNet)
{
	if (eEvent & FG_NET_EVENT_EOF)
	{
		m_pLogModule->LogNormal(ILogModule::LL_INFO_NORMAL, GUID(0, nSockIndex), "FG_NET_EVENT_EOF", "Connection closed", __FUNCTION__, __LINE__);
	}
	else if (eEvent & FG_NET_EVENT_ERROR)
	{
		m_pLogModule->LogNormal(ILogModule::LL_INFO_NORMAL, GUID(0, nSockIndex), "FG_NET_EVENT_ERROR", "Got an error on the connection", __FUNCTION__, __LINE__);
	}
	else if (eEvent & FG_NET_EVENT_TIMEOUT)
	{
		m_pLogModule->LogNormal(ILogModule::LL_INFO_NORMAL, GUID(0, nSockIndex), "FG_NET_EVENT_TIMEOUT", "read timeout", __FUNCTION__, __LINE__);
	}
	else  if (eEvent & FG_NET_EVENT_CONNECTED)
	{
		m_pLogModule->LogNormal(ILogModule::LL_INFO_NORMAL, GUID(0, nSockIndex), "FG_NET_EVENT_CONNECTED", "connected success", __FUNCTION__, __LINE__);
		Register(pNet);
	}
}

void FragrantGrass::WorldToMasterModule::OnClientDisconnect(const SOCK nAddress)
{

}

void FragrantGrass::WorldToMasterModule::OnClientConnected(const SOCK nAddress)
{

}

bool FragrantGrass::WorldToMasterModule::BeforeShut()
{
	return true;
}

void FragrantGrass::WorldToMasterModule::LogServerInfo(const std::string& strServerInfo)
{
	m_pLogModule->LogNormal(ILogModule::LL_INFO_NORMAL, GUID(), strServerInfo, "");
}

void FragrantGrass::WorldToMasterModule::OnServerInfoProcess(const SOCK nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	m_pWorldNetServerModule->OnServerInfoProcess(nSockIndex, nMsgID, msg, nLen);
}
